package com.dq.controller.sys;

import com.dq.annotation.aop.SysLog;
import com.dq.context.Constant;
import com.dq.domain.service.ServiceProject;
import com.dq.domain.service.centre.StaffUserServiceProjectCentre;
import com.dq.domain.sys.role.SysRoleSection;
import com.dq.exception.customException.AdminException;
import com.dq.controller.in.user.SysSectionUserQuery;
import com.dq.utils.ListUtils;
import com.dq.vo.Vo;
import com.dq.domain.org.Org;
import com.dq.domain.position.OrgPosition;
import com.dq.domain.sys.role.SysRole;
import com.dq.domain.sys.role.SysUserRole;
import com.dq.domain.sys.section.SysSection;
import com.dq.domain.sys.user.user.base.BackUser;
import com.dq.domain.sys.user.user.BossUser;
import com.dq.domain.sys.user.user.OrgUser;
import com.dq.domain.sys.user.user.base.SysUser;
import com.dq.service.AllService;
import com.dq.service.TokenService;
import com.dq.utils.BeanNullUtil;
import com.dq.validator.ValidatorUtils;
import com.dq.validator.group.UpdateGroup;
import com.dq.vo.baseVo.VO;
import com.google.gson.ExclusionStrategy;
import com.google.gson.FieldAttributes;
import com.google.gson.Gson;
import com.google.gson.GsonBuilder;
import io.swagger.annotations.Api;
import io.swagger.annotations.ApiOperation;
import io.swagger.annotations.ApiParam;
import org.apache.commons.lang3.StringUtils;
import org.apache.shiro.authz.annotation.RequiresPermissions;
import org.springframework.beans.BeanUtils;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.http.HttpStatus;
import org.springframework.transaction.annotation.Transactional;
import org.springframework.web.bind.annotation.*;

import java.math.BigDecimal;
import java.util.*;

/**
 * 系统用户
 *
 * @author cf
 */
@Api(description = "用户管理(获取bossUser/orgUser,关联组织部门)")
@RestController
@RequestMapping("/sys/userSection/")
public class SysBackUserSectionController extends AllService {
    @Autowired
    TokenService tokenService;

    /**
     * 可以设定是否只显示 自己创建的用户
     */
    @ApiOperation("BackUser用户列表")
    @PostMapping("list")
    @RequiresPermissions("sys:user:list")
    public Vo list(@RequestBody SysSectionUserQuery sectionUserQuery) throws AdminException {

        return backUserService.backUserList(sectionUserQuery);
    }


    @ApiOperation("保存用户(BackUser)")
    @SysLog("保存用户(BackUser)")
    @PostMapping("save")
    @RequiresPermissions("sys:user:save")
    @Transactional(rollbackFor = Exception.class)
    public Vo save(@RequestBody BackUser user) throws AdminException {
        String[] postIds = new String[]{};
        if(StringUtils.isNotBlank(user.getPostIds())) {
            postIds = user.getPostIds().split(",");
        }
        List<Long> roleIds = new ArrayList<>();
        if(StringUtils.isNotBlank(user.getRoleIds())) {
            String[] split = user.getRoleIds().split(",");
            for (String s : split) {
                roleIds.add(Long.parseLong(s));
            }
        }
        if(user.getSectionId() == null) {
            throw new AdminException("所属部门或门店为空");
        }
        SysSection section = dao.get(SysSection.class, user.getSectionId());
        if (section == null || section.getId() == null) {
            throw new AdminException("组织部门不存在");
        }
        List<SysRoleSection> roleSections = sysRoleSectionRepository.findByDeletedFalseAndSection(section);
        for (SysRoleSection roleSection : roleSections) {
            if(ListUtils.listIn(roleSection.getSysRole().getId(), roleIds) < 0) {
                roleIds.add(roleSection.getSysRole().getId());
            }
        }
        user.setSection(section);
        if(postIds.length > 0){
            OrgPosition orgPosition = dao.get(OrgPosition.class,Long.parseLong(postIds[0]));
            if(orgPosition == null){
                throw new AdminException("所选岗位不存在");
            }
            user.setOrgPosition(orgPosition);
        }
        Gson gson = bossUserService.getGson();
        String toJson = gson.toJson(user);
        SysUser sysUser = new SysUser();
//        if(user.getSection() instanceof Org) {
//            OrgUser fromJson = gson.fromJson(toJson, OrgUser.class);
//            sysUser = orgUserService.save(fromJson);
//        }else {
//            BossUser fromJson = gson.fromJson(toJson, BossUser.class);
//            sysUser = bossUserService.save(fromJson);
//        }
        BossUser fromJson = gson.fromJson(toJson, BossUser.class);
        sysUser = bossUserService.save(fromJson);

        // 关联项目: 员工
        saveServiceCentrs(user.getServiceProjectIds(), sysUser);

        if(roleIds.size() > 0){
            List<SysUserRole> sysUserRoles = new ArrayList<>();
            for (int i = 0; i < roleIds.size(); i++) {
                SysRole sysRole = dao.get(SysRole.class, roleIds.get(i));
                if(sysRole == null){
                    throw new AdminException("所选角色不存在");
                }

                SysUserRole sysUserRole = new SysUserRole();
                sysUserRole.setSysRole(sysRole);
                sysUserRole.setSysUser(sysUser);
                sysUserRoles.add(sysUserRole);
                // 设置默认店长
                setOrgShopManage(sysUser, sysRole);
            }
            sysUserRoleRepository.saveAll(sysUserRoles);
        }

        setRatio(sysUser.getId());

        return new Vo(HttpStatus.OK);
    }

    private void setRatio(Long userId) {
        BossUser bossUser = dao.get(BossUser.class, userId);
        if(bossUser.getTopRatio() == null || bossUser.getExpendRatio() == null) {
            List<SysUserRole> userRoles = sysUserRoleRepository.findByDeletedIsFalseAndSysUser(bossUser);
            if(userRoles == null || userRoles.size() <= 0) {
                throw new AdminException("用户未关联角色, 不能设置默认提成比例");
            }
            BigDecimal topRatio = new BigDecimal("0");
            BigDecimal expendRatio = topRatio;
            for (SysUserRole userRole : userRoles) {
                if(userRole.getSysRole().getTopRatio() == null || userRole.getSysRole().getExpendRatio() == null) {
                    throw new AdminException(String.format("用户关联角色: %s, 未设置默认提成比例", userRole.getSysRole().getRoleName()));
                }
                if(userRole.getSysRole().getTopRatio().compareTo(topRatio) > 0) {
                    topRatio = userRole.getSysRole().getTopRatio();
                }
                if(userRole.getSysRole().getExpendRatio().compareTo(expendRatio) > 0) {
                    expendRatio = userRole.getSysRole().getExpendRatio();
                }
            }
            bossUser.setTopRatio(topRatio);
            bossUser.setExpendRatio(expendRatio);
            bossUserService.update(bossUser);
        }
    }

    private void setOrgShopManage(SysUser sysUser, SysRole sysRole) {
        System.out.println(sysRole.getCode());
        System.out.println(Constant.ROLE_CODE_LIST.get(3));
        System.out.println(sysUser.getSection() instanceof Org);

        if(sysRole.getCode().toString().equals(Constant.ROLE_CODE_LIST.get(3))) {
            Org orgGet = dao.get(Org.class, sysUser.getSection().getId());
            if(orgGet != null) {
                if(orgGet.getShopManager() == null) {
                    if(sysUser instanceof BossUser) {
                        orgGet.setShopManager((BossUser) sysUser);
                        orgRepository.save(orgGet);
                    }
                }
            }
        }
    }

    private void saveServiceCentrs(String serviceProjectIds, SysUser sysUser) {
        List<StaffUserServiceProjectCentre> centres = new ArrayList<>();
        if(StringUtils.isNotBlank(serviceProjectIds)) {
            List<StaffUserServiceProjectCentre> centresGet = staffUserServiceProjectCentreRepository.findByDeletedFalseAndStaffUser(sysUser);
            if(centresGet != null && centresGet.size() > 0) {
                staffUserServiceProjectCentreRepository.deleteAll(centresGet);
            }

            String[] serviceProjectIdsArr = serviceProjectIds.split(",");
            if(serviceProjectIdsArr.length > 0) {
                for (String serviceProjectId : serviceProjectIdsArr) {
                    ServiceProject serviceProject = dao.get(ServiceProject.class, Long.parseLong(serviceProjectId));
                    StaffUserServiceProjectCentre staffUserServiceProjectCentre = new StaffUserServiceProjectCentre();
                    staffUserServiceProjectCentre.setServiceProject(serviceProject);
                    staffUserServiceProjectCentre.setStaffUser(sysUser);
                    centres.add(staffUserServiceProjectCentre);
                }
            }
        }
        if(centres.size() > 0) {
            staffUserServiceProjectCentreRepository.saveAll(centres);
        }
    }


    @ApiOperation("修改用户(BackUser)")
    @PostMapping("update/{userId}")
    @RequiresPermissions("sys:user:update")
    @Transactional(rollbackFor = Exception.class)
    public Vo update(@RequestBody BackUser user, @PathVariable @ApiParam(value = "用户id") Long userId) throws AdminException {
        String[] postIds = new String[]{};
        if(StringUtils.isNotBlank(user.getPostIds())) {
            postIds = user.getPostIds().split(",");
        }
        String[] roleIds = new String[]{};
        if(StringUtils.isNotBlank(user.getRoleIds())) {
           roleIds = user.getRoleIds().split(",");
        }
        if(StringUtils.isNotBlank(user.getPassword())) {
            user.setPassword(sysUserService.getPassword(user.getPassword()));
        }

        BackUser backUser = dao.get(BackUser.class, userId);
        if (backUser == null) {
            throw new AdminException("用户不存在");
        }
        Gson gson = bossUserService.getGson();
        String toJson = gson.toJson(backUser);

        if(backUser.getSection() == null) {
            throw new AdminException("所属部门或门店为空");
        }
        if(backUser.getOrgPosition() != null && backUser.getOrgPosition().getId() != null) {
            for (String postId : postIds) {
                if(Long.parseLong(postId) != backUser.getOrgPosition().getId()){
                    OrgPosition orgPosition = dao.get(OrgPosition.class,Long.parseLong(postId));
                    if(orgPosition == null){
                        throw new AdminException("所选岗位不存在");
                    }
                    user.setOrgPosition(orgPosition);
                }
            }
        }
        SysUser sysUser = new SysUser();
//        if(backUser.getSection() instanceof Org) {
//            OrgUser fromJson = gson.fromJson(toJson, OrgUser.class);
//
//            BeanUtils.copyProperties(user, fromJson, BeanNullUtil.getNullPropertyNames(user));
//            ValidatorUtils.validateEntity(fromJson, UpdateGroup.class);
//
//            sysUser = orgUserService.update(fromJson);
//        }else {
//            BossUser fromJson = gson.fromJson(toJson, BossUser.class);
//
//            BeanUtils.copyProperties(user, fromJson, BeanNullUtil.getNullPropertyNames(user));
//            ValidatorUtils.validateEntity(fromJson, UpdateGroup.class);
//
//            sysUser= bossUserService.update(fromJson);
//        }
        BossUser fromJson = gson.fromJson(toJson, BossUser.class);
        BeanUtils.copyProperties(user, fromJson, BeanNullUtil.getNullPropertyNames(user));
        ValidatorUtils.validateEntity(fromJson, UpdateGroup.class);
        sysUser= bossUserService.update(fromJson);

        // 关联项目: 员工
        saveServiceCentrs(user.getServiceProjectIds(), sysUser);

        if(roleIds.length > 0){
            List<SysUserRole> sysUserRoleList = sysUserRoleRepository.findBySysUser(sysUser);
            if(user.getId() == 1L){
                sysUserRoleList.forEach(sysUserRole -> {
                    if(Constant.ADMIN_CODE.equals(sysUserRole.getSysRole().getCode())){
                        throw new AdminException("不能删除超级管理员角色");
                    }
                });
            }
            sysUserRoleRepository.deleteAll(sysUserRoleList);
            List<SysUserRole> sysUserRoles = new ArrayList<>();
            for (int i = 0; i < roleIds.length; i++) {
                SysRole sysRole = dao.get(SysRole.class, Long.parseLong(roleIds[i]));
                if(sysRole == null){
                    throw new AdminException("所选角色不存在");
                }

                SysUserRole sysUserRole = new SysUserRole();
                sysUserRole.setSysRole(sysRole);
                sysUserRole.setSysUser(sysUser);
                sysUserRoles.add(sysUserRole);

                // 设置默认店长
                setOrgShopManage(sysUser, sysRole);
            }
            sysUserRoleRepository.saveAll(sysUserRoles);
        }

        setRatio(sysUser.getId());

        return new Vo(HttpStatus.OK);
    }


    @ApiOperation("删除用户")
    @SysLog("删除用户")
    @DeleteMapping("deletes/{ids}")
    @RequiresPermissions("sys:user:delete")
    public Vo deletes(@PathVariable @ApiParam(value = "用户id") Long[] ids) throws AdminException {
        Gson gson = bossUserService.getGson();
        for (Long id : ids) {
            if (id.toString().equals(String.valueOf(Constant.ADMIN_ID))) {
                throw new AdminException("系统管理员不能被删除");
            }
            if (id.equals(shiroService.getUserId())) {
                throw new AdminException("不能删除登录账号");
            }
            ///
            BackUser backUser = dao.get(BackUser.class, id);
            if(backUser == null) {
                throw new AdminException("无对应账户");
            }
            backUser.setDeleted(true);

            String toJson = gson.toJson(backUser);
//            if(backUser.getSection() instanceof Org) {
//                orgUserService.update(gson.fromJson(toJson, OrgUser.class));
//            }else {
//                bossUserService.update(gson.fromJson(toJson, BossUser.class));
//            }
            bossUserService.update(gson.fromJson(toJson, BossUser.class));
        }

        return new Vo(HttpStatus.OK);
    }

    @ApiOperation("用户详情")
    @GetMapping("userInfo/{userId}")
    @RequiresPermissions("sys:user:list")
    public Vo userInfo(@PathVariable @ApiParam("用户ID") Long userId) throws AdminException {

        BossUser bossUser = dao.get(BossUser.class, userId);
        if(bossUser == null) {
            throw new AdminException("无对应ID用户");
        }
        BossUser.Vo vo = (BossUser.Vo) bossUser.toVO();

        // 关联服务项目: 员工
        Set<ServiceProject.Vo> serviceProjectList = new HashSet<>();
        List<StaffUserServiceProjectCentre> centres = staffUserServiceProjectCentreRepository.findByDeletedFalseAndStaffUser(bossUser);
        for (StaffUserServiceProjectCentre centre : centres) {
            serviceProjectList.add((ServiceProject.Vo) centre.getServiceProject().toVO());
        }
        vo.setServiceProjectList(serviceProjectList);

        return new Vo(vo);
    }

}
